#成员修饰符（公有/私有）
#公有，在任何地方都可以调用这个成员
#私有，只有在类的内部才可以调用该成员（成员是以两个下划线开头，则表示该成员为私有）
# class Foo(object):
#     def __init__(self, name,age):
#         self.__name = name#私有成员
#         self.age = age
#     def  get_data(self):
#         return self.__name
#     def get_age(self):
#         return self.age
# obj=Foo("xiaofeng",22)
# #公有成员
# print(obj.age)
# #私有成员
# #print(obj.__name) #错误，私有成员，只能在类中进行使用
# v2=obj.get_data()
# print(v2)
# class Foo(object):
#     def __get_data(self):
#         print("私有的__get_data")
#     def  get_age(self):
#         print("公有的get_age")
#     def proxy(self):
#         print("公有的proxy")
#         self.__get_data()
# obj=Foo()
# obj.proxy()
# obj.get_age()
# obj.__get_data()  报错

#特别提醒：父类中的私有成员，子类无法继承
#强行访问私有
# class Foo(object):
#     def __init__(self):
#         self.__name = "xiaofeng"
#         self.age = 13
#     def __msg(self):
#         print(1234)
# obj=Foo()
# print(obj.age)
# print(obj._Foo__name)
# obj._Foo__msg()


#“对象嵌套”：
#情景一：
# class Student(object):
#     """学生类"""
#     def __init__(self, name,age):
#         self.name = name
#         self.age = age
#     def message(self):
#         print(f"我是一名学生，我叫{self.name},我今年{self.age}岁.")
# class Classes(object):
#     """班级类"""
#     def __init__(self, title):
#         self.title = title
#         self.stus_lsits = []
#     def add_student(self, stu_obj):
#         self.stus_lsits.append(stu_obj)
#     def add_students(self, stu_list):
#         for stu in stu_list:
#             self.add_student(stu)
#     def display(self):
#         for stu in self.stus_lsits:
#             stu.message()
# s1=Student("xiao",13)
# s2=Student("wang",14)
# s3=Student("zhang",15)
# c1=Classes("三（2）")
# c1.add_student(s1)
# c1.add_students([s2,s3])
# c1.display()

#情景二
# class Student(object):
#     """学生类"""
#     def __init__(self, name,age,class_obj):
#         self.name = name
#         self.age = age
#         self.class_obj = class_obj
#     def message(self):
#         print(f"我是一名学生，我是{self.class_obj.obj}班级，我叫{self.name},我今年{self.age}岁.")
# class Classes(object):
#     """班级类"""
#     def __init__(self, obj):
#         self.obj = obj
# c1=Classes("python全栈")
# c2=Classes("Linux云计算")
# user_obj_list=[Student("小",23,c1),Student("张",21,c2),Student("李",22,c1)]
# for obj in user_obj_list:
#     obj.message()


#情景三：
# class Student(object):
#     """学生类"""
#     def __init__(self, name,age,class_obj):
#         self.name = name
#         self.age = age
#         self.class_obj = class_obj
#     def message(self):
#         print(f"我是一名学生，我在{self.class_obj.school.name}校区{self.class_obj.obj}班级，我叫{self.name},我今年{self.age}岁.")
# class Classes(object):
#     """班级类"""
#     def __init__(self, obj,school):
#         self.obj = obj
#         self.school = school
# class School(object):
#     """学校类"""
#     def __init__(self, name):
#         self.name = name
# s1=School("北新街校区")
# s2=School("丹江校区")
# c1=Classes("python全栈",s1)
# c2=Classes("Linux云计算",s2)
# user_obj_list=[Student("小",23,c1),Student("张",21,c2),Student("李",22,c1)]
# for obj in user_obj_list:
#     obj.message()

#特殊成员：也可以理解为一些特殊的方法  __方法名__
#__init__ 初始化方法
#__new__  构造方法
# class Foo(object):
#     def __init__(self,name):
#         print("第二步，初始化对象，在对象中创建数据")
#         self.name = name
#     def __new__(cls, *args, **kwargs): #不写，会自动调用
#         print("第一步，先创建空对象并返回")
#         return object.__new__(cls)
# obj=Foo("xiao")

#__call__
# class Foo(object):
#     def __call__(self,*args,**kwargs):
#         print("执行call方法")
# obj=Foo()
# obj() #对象（），就会自动执行call方法


#__str__
# class Foo(object):
#     def __str__(self):
#         return "Foo" #必须返回一个字符串
# obj=Foo()
# data=str(obj)
# print(data)

# class Student(object):
#     """学生类"""
#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#     def __str__(self):
#         return f'我叫{self.name}，{self.age}'
# s1=Student('zhang',18)
# print(s1)


#__dict__
# class Student(object):
#     """学生类"""
#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
# s1=Student('zhang',18)
# print(s1.__dict__)

#__getitem__ __setitem__ __delitem__
# 字典的对象支持     对象['']        对象[]=xxx        del 对象[]
# info=dict()
# info["k1"]=123
# info["k2"]=456
# print(info)
# print(info["k1"])
# del info["k1"]
# print(info)
# class myobj(object):
#         def __setitem__(self, key, value):
#             self.value = value
#             print(key, value)
#         def __getitem__(self, key):
#             return self.value
#         def __delitem__(self, key):
#             return key
#
# #通过这种语法都会自动触发
# obj = myobj()
# obj["name"]="xiaowang"
# print(obj["age"])
# del obj["name"]


#__enter__   __exit__  上下文管理
# class Foo(object):
#     def __enter__(self):
#         print("开始")
#         return 666
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         print("结束")
#
# #with 对象      在内部会执行__enter__ 方法
# #当with缩进中的代码执行完毕，就会自动执行__exit__方法
# """obj=Foo()
# with obj as  f:
#     print(222)
#     print(f)
#     """
# with Foo() as  f:
#     print(222)
#     print(f)


#__add__ 等
#对象+值，内部会去执行 对象.__add__方法，并将+后面的值当做参数传过去
# class Foo(object):
#     def __init__(self, age):
#         self.age = age
#     def __add__(self, other):
#         return self.age + other.age
# v1=Foo(12)
# v2=Foo(14)
# print(v1 + v2)


